package cn.zlj.pethome.pet.service.impl;

import cn.zlj.pethome.basic.QueryResult;
import cn.zlj.pethome.basic.config.BussinessException;
import cn.zlj.pethome.basic.dto.AcceptDto;
import cn.zlj.pethome.basic.util.*;
import cn.zlj.pethome.order.domain.OrderPetAcquisition;
import cn.zlj.pethome.order.mapper.OrderPetAcquisitionMapper;
import cn.zlj.pethome.org.domain.Shop;
import cn.zlj.pethome.org.domain.TEmployee;
import cn.zlj.pethome.org.mapper.EmployeeMapper;
import cn.zlj.pethome.org.mapper.ShopMapper;
import cn.zlj.pethome.org.service.EmployeeService;
import cn.zlj.pethome.pet.domain.SearchMasterMsg;
import cn.zlj.pethome.pet.domain.SearchMasterMsgAuditLog;
import cn.zlj.pethome.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.zlj.pethome.pet.mapper.SearchMasterMsgMapper;
import cn.zlj.pethome.pet.query.SearchMasterMsgQuery;
import cn.zlj.pethome.pet.service.ISearchMasterMsgService;
import cn.zlj.pethome.basic.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zlj
 * @since 2022-11-01
 */
@Service
@Slf4j
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {
    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private OrderPetAcquisitionMapper orderMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    @Override
    public AjaxResult publish(SearchMasterMsg searchMasterMsg) {
        //先将寻主消息加入数据库
        super.add(searchMasterMsg);
        //参数校验失败加入审核日志
        isEmpty(searchMasterMsg);
        //百度ai校验错误加入日志
        baiducheack(searchMasterMsg);
        //成功修改状态
        searchMasterMsg.setState(1);
        //进行寻找50公里内的shop找到就加入
        Point point = DistanceUtil.getPoint(searchMasterMsg.getAddress());
        List<Shop> all = shopMapper.findAll();
        Shop nearestShop = DistanceUtil.getNearestShop(point, all);
        //如果在五十公里有商家就将其加入其中
        if (nearestShop != null) {
            searchMasterMsg.setShopId(nearestShop.getId());
            super.update(searchMasterMsg);
        }


        return AjaxResult.me().success();
    }

    @Override
    public QueryResult<SearchMasterMsg> queryByMsgPage(SearchMasterMsgQuery query) {
        // 查询条数

        Integer totals = searchMasterMsgMapper.queryByMsgCount(query);

        if (null == totals || 0 == totals) {
            return new QueryResult<>(0, new ArrayList<>());
        }
        // 查询数据
        List<SearchMasterMsg> searchMasterMsgs = searchMasterMsgMapper.queryByMsgPage(query);
        //方到返回里面
        return new QueryResult<>(totals, searchMasterMsgs);
    }

    /**
     * 拒单把店铺id改为空
     * 添加日志
     *
     * @param msgId
     * @param tEmployee
     */
    @Override
    public void reject(Long msgId, TEmployee tEmployee) {
        SearchMasterMsg s = searchMasterMsgMapper.findById(msgId);
        if (s == null) {
            throw new BussinessException("寻主消息为空");
        }
        s.setShopId(null);
        searchMasterMsgMapper.update(s);
        //添加日志
    }

    @Override
    public void accept(AcceptDto acceptDto) {
        SearchMasterMsg msg = searchMasterMsgMapper.findById(acceptDto.getMsgId());
        //如果寻主消息不存在就抛异常
        if (msg == null) {
            throw new BussinessException("寻主消息不存在");
        }
        //多个员工同时抢寻主消息需要加锁锁寻主消息id
        synchronized (msg.getId()) {
            TEmployee emp = employeeMapper.getOne(acceptDto.getHandler());
            if (emp == null) {
                throw new BussinessException("不存在该员工");
            }
            //判断该员工是否是该店铺的员工和寻主消息是否被接单了
            if (msg.getState() == 1 && emp.getShopId().equals(msg.getShopId())) {
                //修改状态
                msg.setState(2);
                searchMasterMsgMapper.update(msg);
                //生成订单
                addOrder(acceptDto, msg, emp);
            }
        }

    }

    private void addOrder(AcceptDto acceptDto, SearchMasterMsg msg, TEmployee emp) {
        OrderPetAcquisition order = new OrderPetAcquisition();
        order.setOrderSn(CodeGenerateUtils.generateOrderSn(acceptDto.getHandler()));
        order.setDigest(acceptDto.getNote());//+ 24 * 60 * 60 * 1000 * 3
        order.setLastConfirmTime(new Date(System.currentTimeMillis() ));
        order.setState(0);
        order.setPrice(new BigDecimal(msg.getPrice()));
        order.setUserId(msg.getUserId());
        order.setShopId(msg.getShopId());
        order.setAddress(msg.getAddress());
        order.setEmpId(emp.getId());
        order.setSearchMasterMsgId(msg.getId());
        orderMapper.add(order);
        //延时消息的使用限制
        //private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
        //现在RocketMq并不支持任意时间的延时，需要设置几个固定的延时等级，从1s到2h分别对应着等级1到18 消息消费失败会进入延时消息队列
       // MqMessage message = MqMessage.builder().name("延时消息").msg("这是延时消息" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).build();
        SendResult sendResult = rocketMQTemplate.syncSend("springboot_group", MessageBuilder.withPayload(order.getId()).build(), 2000, 4);
     log.info(""+sendResult);
        //rocketMQTemplate.convertAndSend("springboot_group",order.getId());
    }


    private void isEmpty(SearchMasterMsg searchMasterMsg) {
        if (StringUtils.isEmpty(searchMasterMsg.getCoatColor()) || StringUtils.isEmpty(searchMasterMsg.getTitle()) || StringUtils.isEmpty(searchMasterMsg.getAddress()) || StringUtils.isEmpty(searchMasterMsg.getName())) {
            SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setNote("参数为空，审核失败，请在个人中心中进行修改发布！");
            searchMasterMsgAuditLog.setAuditTime(new Date());
            searchMasterMsgAuditLogMapper.add(searchMasterMsgAuditLog);
            throw new BussinessException("参数为空，审核失败，请在个人中心中进行修改发布！");
        }
    }

    private void baiducheack(SearchMasterMsg searchMasterMsg) {
        //百度ai校验
        StringBuilder sb = new StringBuilder()
                .append(searchMasterMsg.getAddress())
                .append(searchMasterMsg.getName())
                .append(searchMasterMsg.getTitle())
                .append(searchMasterMsg.getCoatColor());
        if (!BaiduAuditUtils.TextCensor(sb.toString())) {
            //审核不通过把寻主消息信息加入审核表
            SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setNote("参数非法，审核失败，请在个人中心中进行修改发布！");
            searchMasterMsgAuditLog.setAuditTime(new Date());
            searchMasterMsgAuditLogMapper.add(searchMasterMsgAuditLog);

            throw new BussinessException("参数非法，审核失败，请在个人中心中进行修改发布！");
        }
    }
}
